package cn.ligui.exportsis.utils;

import org.apache.commons.lang3.StringUtils;

import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;


public class CSVUtil {
    /**
     * 功能说明：获取UTF-8编码文本文件开头的BOM签名。
     * BOM(Byte Order Mark)，是UTF编码方案里用于标识编码的标准标记。例：接收者收到以EF BB BF开头的字节流，就知道是UTF-8编码。
     *
     * @return UTF-8编码文本文件开头的BOM签名
     */
    public static String getBOM() {
        byte b[] = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
        return new String(b);
    }

    /**
     * 生成并下载csv文件
     *
     * @param response
     * @param exportData
     * @param maplist
     * @param outPutPath
     * @param fileName
     * @throws IOException
     */
    @SuppressWarnings("rawtypes")
    public static void exportDataFile(List<?> exportData, List<String> titleList, List<String> fieldList, String outPutPath, String fileName) throws IOException {
        File csvFile = null;
        BufferedWriter csvFileOutputStream = null;
        try {
            //定义文件名格式并创建
            csvFile = new File(outPutPath + fileName + ".csv");
            if (csvFile.exists()) {
                csvFile.delete();
            }
            csvFile.createNewFile();
            // UTF-8使正确读取分隔符","
            //如果生产文件乱码，windows下用gbk，linux用UTF-8
            FileOutputStream fileOutputStream = new FileOutputStream(csvFile);
            //加入bom 否则生成的csv文件 用excel乱码
            fileOutputStream.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(fileOutputStream, "UTF-8"), 1024);
//	          //写入前段字节流，防止乱码
//	          csvFileOutputStream.write(getBOM());

            for (int i = 0; i < titleList.size(); i++) {
                String title = titleList.get(i);
                csvFileOutputStream.write(title);
                if (i != (titleList.size() - 1)) {
                    csvFileOutputStream.write(",");
                }
            }
            csvFileOutputStream.newLine();

            NumberFormat nf = NumberFormat.getInstance();
            nf.setGroupingUsed(false);
            nf.setMaximumFractionDigits(7);

            PropertyDescriptor propertyDescriptor;
            //数据导出时，数字类型保留7位小数，保留原始数据
            for (int i = 0; i < exportData.size(); i++) {
                for (int j = 0; j < fieldList.size(); j++) {
                    propertyDescriptor = new PropertyDescriptor(fieldList.get(j), exportData.get(0).getClass());
                    Method readMethod = propertyDescriptor.getReadMethod();
                    Object value = readMethod.invoke(exportData.get(i));
                    if (value != null) {
                        String str = value.toString();
                        if (StringUtils.isBlank(str)) {
                            str = "";
                        } else {
                            try {
                                if (str.contains(".")) {
                                    str = Double.parseDouble(str) + "";
                                    String[] tempArr = str.split("\\.");
                                    if (tempArr.length > 1) {
                                        if (tempArr[1].length() > 5) {
                                            str = nf.format(Double.parseDouble(str));
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                str = str;
                            }

                            //str=str.replaceAll("\"","\"\"");
                            if (str.endsWith(",")) {
                                str = str.substring(0, str.length() - 1);
                            }
                            //str.replaceAll(",", "，");
                            if (str.indexOf("，") >= 0) {
                                str = "\"" + str + "\"";
                            } else if (str.indexOf(",") >= 0) {
                                str = "\"" + str + "\"";
                            }
                            str = str.replaceAll("\n", "");
                            str = str.replaceAll("\r", "");
                            str = str.trim();
                        }
                        csvFileOutputStream.write(str + ","); //文本用双引号包裹

                    } else {
                        csvFileOutputStream.write(","); //文本用双引号包裹
                    }
                }
                csvFileOutputStream.newLine();
            }
            csvFileOutputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                csvFileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
